/**
  ******************************************************************************
  * @file           : state_machine_drv.h
  * @author         : Tessia
  * @brief          : None
  * @attention      : 这个文件来实现哨兵的状态机形容，并作为整个哨兵的决策部分
  * @date           : 2024/3/14
  ******************************************************************************
  */



#ifndef SENTRY_RIGHT_GIMBAL_STATE_MACHINE_DRV_H
#define SENTRY_RIGHT_GIMBAL_STATE_MACHINE_DRV_H

#include "cmsis_os.h"
#include "auto_decision_make_task.h"

typedef void (state_change_callback)(float coo_x, float coo_y);

/**
 * 增改state的时候记得手动更改总数
 * state会传进底盘，state增加时记得顺便改底盘enum
 */
const uint16_t STATE_NUM = 14;

/**
 * 5个一组，方便计数
 */
enum sentry_state{
    standby = 0,                      //待命状态
    attack,                           //进攻状态，该状态需视野中出现敌人
    high_priority_pathfinding,        //高优先级寻路状态，此时寻路不会被打断，不会反击
    mid_priority_pathfinding,         //中优先级寻路状态，此时寻路不会被打断，会反击
    low_priority_pathfinding,         //低优先级寻路状态，此时寻路会被打断

    patrol,                           //巡逻状态，固定几个点的巡逻状态
    stationary_defense,               //原地不动防守状态
    constrained_defense,              //约束防守状态，适用于第一次死亡前，前哨站被击毁后
    error,                            //错误状态，即进入了不该进入的状态转移表
    logic,                            //逻辑状态，在这里面做逻辑处理和强制状态转换

    pursuit,                          //追击状态，此时追击坐标为敌人消失的坐标
    free_defense,                     //自由防守状态，适用于第一次死亡后
    supply,                           //补给状态，弹丸打完或血量低下会进入此状态，attack、patrol、free_defense的补给状态
    go_attack_outpost,                //只推前哨站状态
};

/**
 * 增改event的时候记得手动更改总数
 * event会传进底盘，event增加时记得顺便改底盘enum
 */
const uint16_t EVENT_NUM = 16;

/**
 * 5个一组，方便计数
 */
enum sentry_event{
    none = 0,
    match_begin,                      //比赛开始
    turn_off_auto,                    //关自动模式
    turn_on_auto,                     //开自动模式
    target_detected,                  //目标出现

    target_disappear,                 //目标消失
    being_hit,                        //受击
    ammunition_capacity_reached_limit,//发弹量达到上限
    HP_low,                           //生命值低下
    logic_operate,                    //逻辑操作，作为debug判断，不会有实际用处

    HP_regeneration,                  //生命值恢复
    outpost_HP_low,                   //我方前哨站血量低下
    revive,                           //复活
    outpost_destroyed,                //我方前哨站被击毁
    radar_lock_target,                //雷达锁定目标

    operator_intervene,               //云台手干预
};


struct state_transform{
    sentry_state current_state;//当前状态
    sentry_event event;//事件ID
    sentry_state next_state;//下个状态
};

class sentry_state_machine{
public:
    sentry_state_machine(state_transform (*state_transform_table_)[EVENT_NUM], osSemaphoreId_t *binary_sem_);
    void event_happen(sentry_event event);
    sentry_state get_current_state();
    void go_to_specified_state(sentry_state state);

private:
    state_transform (*state_transform_table)[EVENT_NUM];
    sentry_state state;
public:
    osSemaphoreId_t *binary_sem;
    sentry_state state_last;
    sentry_event last_event; //由于是顺发型所以没有当前事件，debug用
};


#ifdef __cplusplus
extern "C" {
#endif
//C

#ifdef __cplusplus
}
#endif
//C++








#endif //SENTRY_RIGHT_GIMBAL_STATE_MACHINE_DRV_H
